package com.atguigu.gulimall.search.thread;

import java.util.concurrent.*;

//异步、多线程测试
public class ThreadTest {

    /**
     *  ①基础Thread
     *  ②实现Runnable
     *  ③实现Callable
     *  ④线程池
     *      给线程池直接提交任务。
     *      优点：
     *          提高响应时间（不需要临时创建线程）
     *          降低资源消耗（重复利用线程池中的线程）
     *       1、创建
     *          1）、通过工具类：
     *                          Executors.newCachedThreadPool();//core数量是0，及都可以回收
     *                          Executors.newFixedThreadPool();//core和max数量是固定的，且core=max,都不可回收。
     *                          Executors.newScheduledThreadPool();//定时任务线程池
     *                          Executors.newSingleThreadExecutor();//core、max是1，单线程线程池。
     *
     *          2）、手动创建：new ThreadPoolExecutor(...);
     *              七大参数：
     *              corePoolSize：核心线程数；线程创建好后就准备就绪的线程数量。一直存在
     *              maximumPoolSize：最大线程数量；控制资源
     *              keepAliveTime：存活时间；当前线程数量大于corePoolSize核心数量时，空闲线程时间超过存活时间就会被释放（只释放超出核心线程数的那一部分空闲线程）。
     *              TimeUnit:时间单位；
     *              BlockingQueue<Runnable> workQueue：阻塞队列：如果任务很多，超过了当前线程数量，就会将目前多出的任务放在队列里面。只要有线程空闲了，就会去队列里面取出新的任务执行。
     *              ThreadFactory：线程创建工厂。（默认的）
     *              RejectedExecutionHandler：拒绝策略；如果连阻塞队列都满了，按照我们指定的拒绝策略，拒绝执行任务。
     *
     *           工作流程：
     *           ①线程池创建，准备好core数量的线程，准备接受任务
     *           ②core满了，就将进来的新任务放到阻塞队列中，空闲下了的core就会自己去阻塞队列取任务执行
     *           ③阻塞队列放满了，则会直接开新线程，最大开到max指定的数量
     *           ④max满了，就用RejectedExecutionHandler的拒绝策略拒绝任务
     *           ⑤max都执行完了，有很多空闲线程，就根据存活时间，释放去掉core部分的空闲线程
     *
     *              new LinkedBlockingDeque<>() 这个类型的阻塞队列，默认值是Integer的最大值。有可能会导致内存不够。
     *
     */


    public static void main(String[] args) {
        System.out.println("主方法开始...");

        ExecutorService executorService = Executors.newFixedThreadPool(10);

        ThreadPoolExecutor executor = new ThreadPoolExecutor(5,
                200,
                10,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(100000),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );

        System.out.println("主方法结束...");

    }


    static class Test1 implements Callable<Long>{

        @Override
        public Long call() throws Exception {
            System.out.println("异步开始"+Thread.currentThread().getId());
            return Thread.currentThread().getId();
        }
    }

}
